#!/usr/bin/python
# -*- coding: UTF-8 –*-
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
from random import choice
from decimal import *

import zbit.config as config

def sendToBitcoin(content ):
    print('-----------------------开始上传内容', content)

    # 建立本地连接
    rpc_connection = AuthServiceProxy("http://%s:%s@%s:%s"%(config.ruser,config.rpass,config.rpcip,config.rpcport))
    print('connected to local rpc.')

    ## 获取钱包的现状
    listaddressgroupings = rpc_connection.listaddressgroupings()

    ## 按照额度将tx分为两类，然后从大的往小的转
    from_addr={}
    to_addr={}
    for addr in listaddressgroupings:
        for a in addr:
            if a[1] > config.u_limit:
                from_addr[a[0]]=a[1]
            else:
                to_addr[a[0]]=a[1]

    print("候选发钱集合:\n", from_addr)
    print("候选收钱集合:\n", to_addr)

    #随机选取一个
    out_addr=choice(list(from_addr.items()))
    to_addr=choice(list(to_addr.items()))
    print("发钱地址:\n", out_addr)
    print("收钱地址:\n", to_addr)

    # 选择合适的txid
    original_txid = getUsableTxid(rpc_connection,out_addr)

    ## 生成raw transanction 文本
    rawtx = getRawTx(rpc_connection,out_addr,to_addr,original_txid,content)

    ## 事务签名
    signedRawTx = signRawTx(rpc_connection,rawtx)

    #发送事务
    sendTx(rpc_connection,signedRawTx)

    #记录本次事务id，以备后查


def getUsableTxid(rpc_connection,out_addr):
    "从指定的地址中找到一个合适的txid，其内容要大于转走的钱 config.amout"

    ## 分析发钱地址的uspent
    unspent=rpc_connection.listunspent(config.confirms_min,config.confirms_max,[out_addr[0]])
    
    #太多了，仅测试打印
    #print('unspent\n', unspent)

    txid = ''
    #从unspent中选取合适的txid
    for tx in unspent:
        if tx['amount']>config.amout:
            txid = tx['txid']
            break
    print('选择的事务id ', txid)
    return txid

def getRawTx(rpc_connection,out_addr,to_addr,original_txid,content):
    #参数判断
    if len(content) > 159:
        raise RuntimeError("上链内容过大")

    #转账金额
    amount = config.amout

    print( "转账金额",amount)

    #余额
    left=-1

    ##分析 vout的位置
    vout = -1
    tx = rpc_connection.gettransaction(original_txid)
    print( '原始事务信息 ',tx)
    for d in tx['details']:
        print("look ",d)
        if d['address']==out_addr[0] and d['amount'] > amount:
            print("select ",d)

            vout=d['vout']
            left=d['amount']-amount-config.fee()

            break

    print( 'vout=',vout)
    print( '余额=',vout)

    inputs = [
        {
            "txid":original_txid,
            "vout":vout
        }
    ]

    outputs=[
        { to_addr[0] : str(amount) },
        { out_addr[0] : str(left) },
        { "data" : content}
    ]

    print('原始事务字符串 ',inputs, outputs)

    rawtx = rpc_connection.createrawtransaction(inputs,outputs)
    print('生成的事务  ', rawtx)
    
    ## 记录本次事务id
    recordTxid(rpc_connection,rawtx)

    return rawtx

def signRawTx(rpc_connection,rawtx):
    "给事务签名"
    s = rpc_connection.signrawtransactionwithwallet(rawtx)
    print('签名后的事务 ',s)

    if s['complete'] :
        return s['hex']
    else:
        raise RuntimeError("签名出现错误！")


def recordTxid(rpc_connection,signRawTx):
    "记录本次事务id"
    #todo

    rs = rpc_connection.decoderawtransaction(signRawTx)
    print("解码的内容", rs)

    #todo 将事务id保存起来
    print("新的事务id", rs['txid'])

    # 试图查询一下.不存在会抛出异常 
    try:
        q = rpc_connection.getrawtransaction(rs['txid'])
        print('查询结果',q)
    except JSONRPCException as e:
        print( '没有找到！')


def sendTx(rpc_connection,signedRawTx):
    "向网络发送事务"
    rs = rpc_connection.sendrawtransaction(signedRawTx)
    print("发送事务结果 ",rs)

